package org.spring.aicloud.utils.idempotent;

import cn.hutool.crypto.SecureUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.spring.aicloud.entity.SecurityUserDetails;
import org.spring.aicloud.utils.SecurityUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.concurrent.TimeUnit;
import java.lang.reflect.Method;

/**
 * @author yexiebao
 * @date 2025/5/29
 */
@Component
public class IdempotentInterceptor implements HandlerInterceptor {
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private RedisTemplate redisTemplate;


    /**
     * 拦截处理
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Idempotent idempotent = null;
            try{
                idempotent = ((HandlerMethod)handler)
                        .getMethod().getAnnotation(Idempotent.class);
            }catch (Exception e){
            }
            if(idempotent != null){
                String id = createId(request);
                if( redisTemplate.hasKey(id)){
                    return false;
                }else{
                    redisTemplate.opsForValue().set(id, "", idempotent.expireTime(),TimeUnit.SECONDS);
                    return true;
                }
            }
            return HandlerInterceptor.super.preHandle(request, response, handler);
        }

    /**
     * 创建幂等ID:md5(用户id+请求参数）
     * @param request
     * @return
     */
    private String createId(HttpServletRequest request) throws JsonProcessingException {
        Long uid = 0L;
        SecurityUserDetails currentUser = SecurityUtil.getCurrentUser();
        if(currentUser != null){
            uid = currentUser.getUid();
        }
        String requestParam =  objectMapper.writeValueAsString(request.getParameterMap());
        return SecureUtil.md5(uid + requestParam);
    }
}